
using System;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class GameUser
{
    protected long m_Id;
    public long id => m_Id;

    protected string m_Name;
    public string name => m_Name;
    /// <summary>
    /// 金币
    /// </summary>
    protected float m_Coin;
    public float coin => m_Coin;

    protected int m_Diamond;
    public int diamond => m_Diamond;
    /// <summary>
    /// level
    /// </summary>
    protected int m_Level;
    public int level => m_Level;

    /// <summary>
    /// 已获取的登录奖励
    /// </summary>
    protected List<int> m_AcquiredDailyReward;
    public List<int> acquiredDailyReward => m_AcquiredDailyReward;

    /// <summary>
    /// loginDays
    /// </summary>
    protected int m_LoginDays;
    public int loginDays => m_LoginDays;

    protected List<int> m_LevelStars;
    public List<int> levelStars => m_LevelStars;

    protected long m_MemberTimeEndDate;
    public long memberTimeEndDate => m_MemberTimeEndDate;

    public void Init(LocalUserData localUserData)
    {
        m_Id = localUserData.id;

        this.m_Coin = localUserData.coin;
        this.m_Diamond = localUserData.diamond;
        this.m_Level = localUserData.level;
        this.m_MemberTimeEndDate = localUserData.memberTimeEndDate;
        this.m_Name = localUserData.name;
        
        if (localUserData.acquiredDailyRewared != null)
        {
            this.m_AcquiredDailyReward = new List<int>(localUserData.acquiredDailyRewared);
        }

        this.m_LoginDays = localUserData.loginDays;
        
        _Init(localUserData);

        int curLoginDay = System.DateTime.Now.Day;
        if (curLoginDay != lastLoginDay)
        {
            m_LoginDays++;
            lastLoginDay = curLoginDay;
            GameDebug.LogError($"Login Days +1:{m_LoginDays}");
            UpdateLocalData();
        }
    }

    protected virtual void _Init(LocalUserData localUserData)
    {

    }

    private const string LastLoginDayKey = "LastLoginDay_Key";

    /// <summary>
    /// lastLoginDay
    /// </summary>
    protected static int lastLoginDay
    {
        get { return PlayerPrefs.GetInt(LastLoginDayKey); }
        set { PlayerPrefs.SetInt(LastLoginDayKey, value); }
    }


    public static Action<int> onUpdateDiamond;

    public void UpdateDiamond(int diamond, bool updateRemote = true)
    {
        this.m_Diamond = diamond;

        UpdateLocalData();

        onUpdateDiamond?.Invoke(diamond);
    }

    public static Action<float> onUpdateCoin;

    public void UpdateCoin(float coin, bool updateRemote = true)
    {
        GameDebug.Log($"UpdateCoin:{m_Coin}");
        this.m_Coin = coin;

        if(updateRemote)
            UpdateLocalData();

        onUpdateCoin?.Invoke(coin);
    }

    public static Action<int> onUpdateCard;


    public void UpdateLevel(int level)
    {
        this.m_Level = level;

        UpdateLocalData();
    }

    public void UpdateLocalData()
    {
        string str = Newtonsoft.Json.JsonConvert.SerializeObject(GetLocalUserData());

        System.IO.File.WriteAllText(savePath(this.id), str);

        //PlayerPrefs.SetString(Game.LocalUserDataKey, str);

        GameDebug.Log($"UpdateLocalData:{str}");
    }

    public static string savePath(long user)
    {
        //get
        {
            string folder = Application.persistentDataPath;
            if (!System.IO.Directory.Exists(folder))
            {
                System.IO.Directory.CreateDirectory(folder);
#if UNITY_IOS || UNITY_IPHONE
                GameDebug.Log("savePath,folder:" + folder);
                UnityEngine.iOS.Device.SetNoBackupFlag(folder);
#endif
            }
            return folder + $"/user_data_{user}.data";
        }
    }


    public virtual LocalUserData GetLocalUserData()
    {
        return LocalUserData.User2Data(this);
    }

    public void ReduceCoin(int num, bool updateData = true)
    {
        float coin = this.m_Coin - num;
        GameDebug.Log($"coin :{m_Coin} num:{num} to:{coin}");
        coin = Mathf.Max(0, coin);
        UpdateCoin(coin,updateData);
    }

    public void AddCoin(int num, bool updateData = true)
    {
        float coin = m_Coin + num;
        coin = Mathf.Max(0, coin);
        UpdateCoin(coin,updateData);
    }

    public void ReduceDiamond(int num, bool updateData = true)
    {
        int diamond = this.m_Diamond - num;
        diamond = Mathf.Max(0, diamond);
        UpdateDiamond(diamond, updateData);
    }

    public void AddDiamond(int num, bool updateData = true)
    {
        int diamond = this.m_Diamond + num;
        diamond = Mathf.Max(0, diamond);
        UpdateDiamond(diamond, updateData);
    }

    public void UpdateLevelStar(int level, int star)
    {
        int index = level - 1;
        if (index < m_LevelStars.Count)
        {
            if (this.m_LevelStars[index] < star)
            {
                this.m_LevelStars[index] = star;
            }
        }
        else
        {
            GameDebug.LogError($"m_LevelStars.Count:{m_LevelStars.Count}   level:{level}");
        }
    }


    public int GetStar(int level)
    {
        return 0;
        int index = level - 1;
        if (index < m_LevelStars.Count)
        {
            return this.m_LevelStars[index];
        }
        else
        {
            GameDebug.LogError($"m_LevelStars.Count:{m_LevelStars.Count}   level:{level}");
            return 0;
        }
    }


}


